package com.example.demo.controller;

import com.example.demo.aiInterface.AssistantFactory;
import com.example.demo.aiInterface.BaseAssistantImpl;
import com.example.demo.dao.ChatMessageDao;
import com.example.demo.dao.ChatSessionDao;
import com.example.demo.entity.pojo.ChatMessage;
import com.example.demo.entity.pojo.ChatSession;
import com.example.demo.entity.dto.TokenUserDto;
import com.example.demo.entity.vo.ResponseVO;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import reactor.core.publisher.Flux;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/chat")
public class AiController extends BaseController{

    private static final Logger logger = LoggerFactory.getLogger(AiController.class);

    @Autowired
    private ChatMessageDao chatMessageDao;

    @Autowired
    private ChatSessionDao chatSessionDao;
    
    @Autowired
    private AssistantFactory assistantFactory;

    @PostMapping(value = "/streamChat", produces = "text/stream;charset=utf-8")
    public Flux<String> chat(@RequestParam String sessionId, @RequestParam String userMessage) {
        if (StringUtils.isBlank(sessionId) || StringUtils.isBlank(userMessage)) {
            logger.error("聊天请求参数无效: sessionId={}, messageLength={}", 
                    sessionId, userMessage != null ? userMessage.length() : 0);
            return Flux.error(new ResponseStatusException(HttpStatus.BAD_REQUEST, "会话ID和消息内容不能为空"));
        }
        
        logger.info("收到聊天请求: sessionId={}, message={}", sessionId, 
                userMessage.length() > 50 ? userMessage.substring(0, 50) + "..." : userMessage);
        
        try {
            // 保存用户消息到数据库
            saveUserMessage(sessionId, userMessage);
            
            // 查询会话类型
            List<ChatSession> sessions = chatSessionDao.queryAllBySessionId(sessionId);
            if (sessions == null || sessions.isEmpty()) {
                logger.error("会话不存在: sessionId={}", sessionId);
                return Flux.error(new ResponseStatusException(HttpStatus.NOT_FOUND, "会话不存在"));
            }
            
            ChatSession session = sessions.get(0);
            Integer sessionType = session.getSessionType();
            
            // 使用工厂类获取对应的AI助手
            BaseAssistantImpl assistant = assistantFactory.getAssistant(sessionType);
            return assistant.chat(sessionId, userMessage);
        } catch (Exception e) {
            logger.error("处理聊天请求时发生错误", e);
            return Flux.error(new ResponseStatusException(
                    HttpStatus.INTERNAL_SERVER_ERROR, "处理聊天请求时发生错误"));
        }
    }

    /**
     * 保存用户消息
     */
    private void saveUserMessage(String sessionId, String message) {
        try {
            ChatMessage chatMessage = new ChatMessage();
            chatMessage.setSessionId(sessionId);
            chatMessage.setMessageType(0); // 0表示用户消息
            chatMessage.setMessageContent(message);
            chatMessage.setSendTime(System.currentTimeMillis());
            chatMessage.setStatus(1); // 已发送状态
            chatMessageDao.insert(chatMessage);
            logger.debug("用户消息已保存: sessionId={}, messageId={}", sessionId, chatMessage.getMessageId());
        } catch (Exception e) {
            logger.error("保存用户消息失败: sessionId={}", sessionId, e);
            throw e; // 重新抛出异常以便上层处理
        }
    }

    /**
     * 创建新的聊天会话
     * @param sessionType 会话类型：0=普通助手(默认)，1=Java编程助手
     */
    @PostMapping("/createSession")
    public ResponseVO createSession(HttpServletRequest request, 
                                  @RequestParam(required = false) String title,
                                  @RequestParam(required = false, defaultValue = "0") Integer sessionType) {
        TokenUserDto tokenUserDto = getTokenUserDto(request);
        if(tokenUserDto == null) {
            logger.warn("创建会话失败: 用户未登录或会话已过期");
            return getFail("登录超时！");
        }
        
        try {
            // 生成会话ID
            String sessionId = "S" + RandomStringUtils.randomNumeric(20);
            
            // 如果标题为空，则使用默认标题
            if (StringUtils.isBlank(title)) {
                if (sessionType == 1) {
                    title = "Java编程助手 " + System.currentTimeMillis();
                } else {
                    title = "新对话 " + System.currentTimeMillis();
                }
            }
            
            logger.info("创建新会话: userId={}, sessionId={}, title={}, sessionType={}", 
                    tokenUserDto.getUserId(), sessionId, title, sessionType);
            
            ChatSession chatSession = new ChatSession();
            chatSession.setUserId(tokenUserDto.getUserId());
            chatSession.setSessionId(sessionId);
            chatSession.setTitle(title);
            chatSession.setSessionType(sessionType);
            
            chatSessionDao.insert(chatSession);
            
            Map<String, Object> result = new HashMap<>();
            result.put("sessionId", sessionId);
            result.put("title", title);
            result.put("sessionType", sessionType);
            
            return getSuccess("创建成功！", result);
        } catch (Exception e) {
            logger.error("创建会话失败: userId={}", tokenUserDto.getUserId(), e);
            return getFail("创建会话失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户的会话列表
     */
    @GetMapping("/sessions")
    public ResponseVO getSessions(HttpServletRequest request) {
        TokenUserDto tokenUserDto = getTokenUserDto(request);
        if(tokenUserDto == null) {
            logger.warn("获取会话列表失败: 用户未登录或会话已过期");
            return getFail("登录超时！");
        }
        
        try {
            // 获取用户的所有会话
            List<ChatSession> sessions = chatSessionDao.queryAllByLimit(tokenUserDto.getUserId());
            logger.info("获取会话列表成功: userId={}, sessionCount={}", 
                    tokenUserDto.getUserId(), sessions.size());
            
            return getSuccess("获取成功！", sessions);
        } catch (Exception e) {
            logger.error("获取会话列表失败: userId={}", tokenUserDto.getUserId(), e);
            return getFail("获取会话列表失败: " + e.getMessage());
        }
    }

    /**
     * 根据会话类型获取用户的会话列表
     */
    @GetMapping("/sessionsByType")
    public ResponseVO getSessionsByType(HttpServletRequest request, 
                                       @RequestParam(required = false, defaultValue = "0") Integer sessionType) {
        TokenUserDto tokenUserDto = getTokenUserDto(request);
        if(tokenUserDto == null) {
            logger.warn("获取会话列表失败: 用户未登录或会话已过期");
            return getFail("登录超时！");
        }
        
        try {
            // 根据会话类型获取用户的会话
            List<ChatSession> sessions = chatSessionDao.queryAllByUserIdAndSessionType(
                    tokenUserDto.getUserId(), sessionType);
            logger.info("获取会话列表成功: userId={}, sessionType={}, sessionCount={}", 
                    tokenUserDto.getUserId(), sessionType, sessions.size());
            
            return getSuccess("获取成功！", sessions);
        } catch (Exception e) {
            logger.error("获取会话列表失败: userId={}, sessionType={}", 
                    tokenUserDto.getUserId(), sessionType, e);
            return getFail("获取会话列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定会话的聊天记录
     */
    @GetMapping("/messages")
    public ResponseVO getMessages(@RequestParam String sessionId) {
        if (StringUtils.isBlank(sessionId)) {
            logger.warn("获取聊天记录失败: 会话ID为空");
            return getFail("会话ID不能为空");
        }
        
        try {
            ChatMessage query = new ChatMessage();
            query.setSessionId(sessionId);
            
            // 查询聊天记录
            List<ChatMessage> messages = chatMessageDao.queryAllBySessionId(sessionId);
            logger.info("获取聊天记录成功: sessionId={}, messageCount={}", 
                    sessionId, messages.size());
            
            return getSuccess("获取成功！", messages);
        } catch (Exception e) {
            logger.error("获取聊天记录失败: sessionId={}", sessionId, e);
            return getFail("获取聊天记录失败: " + e.getMessage());
        }
    }

    /**
     * 删除会话
     */
    @PostMapping("/deleteSession")
    @Transactional
    public ResponseVO deleteSession(HttpServletRequest request, @RequestParam String sessionId) {
        TokenUserDto tokenUserDto = getTokenUserDto(request);
        if(tokenUserDto == null) {
            logger.warn("删除会话失败: 用户未登录或会话已过期");
            return getFail("登录超时！");
        }

        if (StringUtils.isBlank(sessionId)) {
            logger.warn("删除会话失败: 会话ID为空");
            return getFail("会话ID不能为空");
        }

        try {
            // 检查会话是否属于当前用户
            List<ChatSession> sessions = chatSessionDao.queryAllByUserIdAndSessionId(
                    tokenUserDto.getUserId(), sessionId);

            if (sessions == null || sessions.isEmpty()) {
                logger.warn("删除会话失败: 会话不存在或不属于当前用户, userId={}, sessionId={}", 
                        tokenUserDto.getUserId(), sessionId);
                return getFail("会话不存在或无权操作");
            }

            // 先删除会话相关的所有消息
            chatMessageDao.deleteBySessionId(sessionId);
            logger.info("删除会话相关消息成功: sessionId={}", sessionId);

            // 然后删除会话
            ChatSession session = sessions.get(0);
            chatSessionDao.deleteById(session.getSessionId());
            logger.info("删除会话成功: userId={}, sessionId={}", tokenUserDto.getUserId(), sessionId);

            return getSuccess("删除成功", null);
        } catch (Exception e) {
            logger.error("删除会话失败: userId={}, sessionId={}, error={}", 
                    tokenUserDto.getUserId(), sessionId, e.getMessage(), e);
            return getFail("删除会话失败: " + e.getMessage());
        }
    }
}
